'''
Created on Jul 5, 2012

@author: nzhao
'''

from traits.api import HasTraits, Float, Int, String, Instance, Bool
from traitsui.api import View, HGroup, Group, Item, RangeEditor, InstanceEditor

import numpy as np

class DynamicRangeFloat(HasTraits):
    show_name = Bool(False)
    name = String()
    min_val = Float
    max_val = Float
    value = Float
    
    def __init__(self, name = 'Variable:', min_val = 0.0, max_val = 1.0, value = 0.0, show_name = False):
        self.name      = name
        self.min_val   = min_val
        self.max_val   = max_val
        self.value     = value
        self.show_name = show_name
        
    def set_val(self,val):
        self.value = val

    trait_view = View(
                      HGroup(Item('name', show_label=False, style='readonly', defined_when = 'show_name'),
                             Item('min_val', show_label=False),
                             Item('max_val', show_label=False),
                             Item('value', editor=RangeEditor(low_name = 'min_val', high_name = 'max_val', mode = 'xslider'), show_label = False),
                             ),
                      )

class DynamicRangeInt(HasTraits):
    show_name = Bool(True)
    name = String()
    min_val = Int
    max_val = Int
    value = Int
    
    def __init__(self, name = 'Variable:', min_val = 0, max_val = 10, value = 0, show_name = True):
        self.name      = name
        self.min_val   = min_val
        self.max_val   = max_val
        self.value     = value
        self.show_name = show_name


    trait_view = View(
                      HGroup(Item('name', show_label=False, style='readonly', defined_when = 'show_name'),
                             Item('min_val', show_label=False),
                             Item('max_val', show_label=False),
                             Item('value', editor=RangeEditor(low_name = 'min_val', high_name = 'max_val', mode = 'xslider' ), show_label = False),
                             ),
                      )
        
class VectorRangePolar(HasTraits):
    name = String()
    magnitude = Instance(DynamicRangeFloat)
    theta     = Instance(DynamicRangeFloat)
    phi       = Instance(DynamicRangeFloat)
    x         = Float(0.0)
    y         = Float(0.0)
    z         = Float(0.0)
    
    def __init__(self, name = 'Vector', value_range = (0.0, 10.0), theta_range = (0.0, 180.0), phi_range = (0.0, 360.0) ):
        self.name = name
        self.magnitude = DynamicRangeFloat(name,    min_val=value_range[0], max_val=value_range[1], value=value_range[0], show_name= False)
        self.theta     = DynamicRangeFloat('theta', min_val=theta_range[0], max_val=theta_range[1], value=theta_range[0], show_name= False)
        self.phi       = DynamicRangeFloat('phi',   min_val=phi_range[0],   max_val=phi_range[1],   value=phi_range[0]  , show_name= False)
        self.update_xyz()
        
        self.magnitude.on_trait_change( self.update_xyz, 'value')
        self.theta.on_trait_change(     self.update_xyz, 'value')
        self.phi.on_trait_change(       self.update_xyz, 'value')
    def update_xyz(self):
        self.x = self.magnitude.value * np.sin(self.theta.value) * np.cos(self.phi.value)
        self.y = self.magnitude.value * np.sin(self.theta.value) * np.sin(self.phi.value)
        self.z = self.magnitude.value * np.cos(self.theta.value)
    
    trait_view=View(Item('name', show_label=True, style='readonly'),
                    Group(
                          Item('magnitude', style= 'custom', label = 'Magnitude', show_label = True),
                          Item('theta',     style= 'custom', label = 'Theta    ', show_label = True),
                          Item('phi',       style= 'custom', label = 'Phi      ', show_label = True),
                          )
                    )
    
class VectorRangeXYZ(HasTraits):
    name = String()
    x = Instance(DynamicRangeFloat)
    y = Instance(DynamicRangeFloat)
    z = Instance(DynamicRangeFloat)
    magnitude = Float(0.0)
    theta     = Float(0.0)
    phi       = Float(0.0)
    
    def __init__(self, name = 'Vector', x_range = (0.0, 10.0), y_range = (0.0, 10.0), z_range = (0.0, 10.0) ):
        self.name = name
        self.x = DynamicRangeFloat('x', min_val=x_range[0], max_val=x_range[1], value=x_range[0], show_name= True)
        self.y = DynamicRangeFloat('y', min_val=y_range[0], max_val=y_range[1], value=y_range[0], show_name= True)
        self.z = DynamicRangeFloat('z', min_val=z_range[0], max_val=z_range[1], value=z_range[0], show_name= True)
        self.update_angles()
        
        self.x.on_trait_change(self.update_angles, 'value')
        self.y.on_trait_change(self.update_angles, 'value')
        self.z.on_trait_change(self.update_angles, 'value')
    
    def update_angles(self):
        pass
    
    trait_view=View(Group(
                          Item('name', show_label=True, style='readonly'),
                          Item('x', style= 'custom', show_label = False),
                          Item('y', style= 'custom', show_label = False),
                          Item('z', style= 'custom', show_label = False),
                          )
                    )

if __name__ == '__main__':
    r=VectorRangeXYZ()
    r.configure_traits()
